import { EventSettings } from '../../types/EventSetting.t'
import { resultFailure, resultSuccess } from '../../utils/resultFormatter'
import { prisma } from '../index.repo'

export const createEvent = async (
    orgId: string,
    title: string,
    description: string,
    { startAt, endAt }: { startAt?: Date | null; endAt?: Date | null }
) => {
    try {
        const result = await prisma.event.create({
            data: {
                organizationId: orgId,
                status: true,
                title,
                description,
                startAt,
                endAt
            }
        })

        if (!result) return resultFailure(false, 500, 'Failed to create event')

        return resultSuccess(true, 201, result, 'Event created successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const createEventWithSettings = async (
    orgId: string,
    title: string,
    description: string,
    { startAt, endAt }: { startAt?: Date | null; endAt?: Date | null },
    settings: EventSettings[]
) => {
    try {
        const result = await prisma.$transaction(async tx => {
            const event = await tx.event.create({
                data: { organizationId: orgId, status: true, title, description, startAt, endAt }
            })
            await tx.eventSetting.create({
                data: { eventId: event.id, value: settings }
            })
            return event
        })

        if (!result) return resultFailure(false, 500, 'Failed to create event')

        return resultSuccess(true, 201, { event: result, settings }, 'Event created successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const deleteEvent = async (eId: string) => {
    try {
        const result = await prisma.$transaction(async tx => {
            await tx.eventSetting.updateMany({
                where: { eventId: eId },
                data: { deletedAt: new Date() }
            })
            await tx.event.updateMany({
                where: { id: eId },
                data: { deletedAt: new Date() }
            })
            return true
        })

        if (!result) return resultFailure(false, 500, 'Failed to delete event')

        return resultSuccess(true, 200, result, 'Event deleted successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const updateEvent = async (
    eId: string,
    title: string,
    description: string,
    { startAt, endAt }: { startAt?: Date | null; endAt?: Date | null }
) => {
    try {
        const result = await prisma.event.update({
            where: { id: eId },
            data: { title, description, startAt, endAt }
        })

        if (!result) return resultFailure(false, 500, 'Failed to update event')

        return resultSuccess(true, 200, result, 'Event updated successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const updateEventSettings = async (eId: string, settings: EventSettings[]) => {
    try {
        const result = await prisma.eventSetting.updateMany({
            where: { eventId: eId },
            data: { value: settings }
        })

        if (!result) return resultFailure(false, 500, 'Failed to update event settings')

        return resultSuccess(true, 200, result, 'Event settings updated successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const updateEventWithSettings = async (
    eId: string,
    title: string,
    description: string,
    { startAt, endAt }: { startAt?: Date | null; endAt?: Date | null },
    settings: EventSettings[]
) => {
    try {
        const result = await prisma.$transaction(async tx => {
            const event = await tx.event.update({
                where: { id: eId },
                data: { title, description, startAt, endAt }
            })
            await tx.eventSetting.updateMany({
                where: { eventId: eId },
                data: { value: settings }
            })
            return event
        })

        if (!result) return resultFailure(false, 500, 'Failed to update event')
        return resultSuccess(true, 200, { event: result, settings }, 'Event updated successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const readEventList = async (orgId: string | undefined = undefined, offset: number = 0, limit: number = 10) => {
    try {
        const result = await prisma.event.findMany({
            where: { organizationId: orgId, deletedAt: null },
            skip: offset,
            take: limit
        })

        if (!result) return resultFailure(false, 404, 'No events found')

        return resultSuccess(true, 200, result, 'Event list retrieved successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const readEvent = async (eId: string) => {
    try {
        const result = await prisma.event.findUnique({
            where: { id: eId },
            include: {
                EventSetting: true
            }
        })

        if (!result) return resultFailure(false, 404, 'Event not found')

        return resultSuccess(true, 200, result, 'Event retrieved successfully')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}

export const checkEventExists = async (eId: string) => {
    try {
        const result = await prisma.event.findUnique({
            where: { id: eId }
        })

        if (!result) return resultFailure(false, 404, 'Event not found')

        return resultSuccess(true, 200, true, 'Event exists')
    } catch (err) {
        return resultFailure(false, 500, String(err))
    }
}
